import GameControl_red_blue_man from "./GameControl_red_blue_man";
import GameData_red_blue_man, {emitType} from "./GameData_red_blue_man";
import ControlScript from "../PublicScript/ControlScript";
import GameOver from "./GameOver";
import Music, {musicName} from "../PublicScript/Music";
import Skeleton = sp.Skeleton;
import SkinShop from "./SkinShop";
import Setting from "./Setting";
import LoadShow from "./LoadShow";
import Resurgence from "./Resurgence";
import Welcome from "./Welcome";

const {ccclass, property} = cc._decorator;

export enum animName {
    idle = "daiji",                 //待机
    run = "run",                    //行走
    push = "push",                  //推物体
    jump1 = "jump1",                //跳跃
    jump2 = "jump2",
    cheer = "cheer",                //胜利
    celebrate1 = "celebrate1",      //招手
    celebrate2 = "celebrate2"       //胜利
}

export enum effectAnimName {
    die = "die",
    animation = "animation",
    smoke2 = "smoke2",
    animation2 = "animation2",
}

export enum colorType {
    red = 0,
    blue = 1,
}

@ccclass
export default class HeroControl extends cc.Component {

    @property({displayName:"移动速度"})
    speed: number = 0;
    @property({displayName:"跳跃高度"})
    jumpNum: number = 0;
    @property({displayName:"英雄可跳跃次数"})
    jumpCount: number = 0;
    @property({tooltip: "人物动画节点", type: cc.Node})
    spineNode: cc.Node = null;
    @property({tooltip: "特效动画节点", type: cc.Node})
    effectSpineNode: cc.Node = null;
    @property({tooltip: "人物颜色", type: cc.Enum(colorType)})
    manType: colorType = colorType.red;
    @property({tooltip: "是否开启自定义跳跃"})
    custom: boolean = false;

    //hero刚体
    heroRigidBody = null;
    //跳跃锁
    jumpLock = false;
    // isContact = false;
    //下跳
    // downMoveLock = false;
    // downMove = false;
    //计算现在英雄所跳跃的次数
    jumpCountIndex = 0;
    //刚体包围盒
    node_phy_box = null;
    //移动锁
    move_lock = false;
    //动画组件
    spineComponent = null;
    effectSpineComponent = null;
    //角色的状态
    animState = animName.idle;
    //前一步的动画状态
    lastAnimState = null;
    //是否在播放行走动画的特效
    playRunEffect = false;
    //是否碰撞着门
    contactDoor = false;
    //拿到对应的门
    doorPos = null;
    //是否在推墙
    pushTheItems = true;
    //播放退石头动画
    pushStoneAnim = false;
    //是否人在移动板上
    onMoveSide = false;
    //初始位置
    initPos = cc.v2();

    onLoad () {

    }

    start () {

    }

    static manSkinName = null;

    //增加移动速度
    addSpeed = false;
    newExperienceSkin(name, state?){
        if(state){
            return;
        }
        this.addSpeed = true;

        this.speed *= 1.3;
        console.log(this.speed);

        HeroControl.manSkinName = name;

        if(this.manType == colorType.red){
            this.spineComponent.setSkin("red" + name);
        }else{
            this.spineComponent.setSkin("blue" + name);
        }
    }

    init(){
        this.heroRigidBody = this.node.getComponent(cc.RigidBody);
        this.node_phy_box = this.node.getComponent(cc.PhysicsBoxCollider);
        // console.log(this.node_phy_box);
        this.spineComponent = this.spineNode.getComponent(sp.Skeleton);
        this.effectSpineComponent = this.effectSpineNode.getComponent(sp.Skeleton);
        cc.game.on(emitType.gameOver, this.gameOver, this);
        cc.game.on(emitType.overAnim, this.overAnim, this);
        cc.game.on(emitType.overAnimFollowUp, this.overGameFollowUp, this);
        cc.game.on(emitType.newSkinExper, this.newExperienceSkin, this);
        cc.game.on(emitType.resurgence, this.resurgence, this);
        console.log("----------------------");

        this.node.getPosition(this.initPos);
        cc.loader.loadRes("Anim/nanhlr", sp.SkeletonData, (err, res)=>{
            this.spineComponent.skeletonData = res;
            if(this.manType == colorType.red){
                if(HeroControl.manSkinName){
                    this.spineComponent.setSkin("red" + HeroControl.manSkinName);
                }else{
                    if(SkinShop.experienceSkinIndex != null){
                        this.spineComponent.setSkin("red" + SkinShop.experienceSkinIndex);
                    }else{
                        this.spineComponent.setSkin("red" + GameData_red_blue_man.usingSkinIndex);
                    }
                }

            }else if(this.manType == colorType.blue){
                if(HeroControl.manSkinName){
                    this.spineComponent.setSkin("blue" + HeroControl.manSkinName);
                }else{
                    if(SkinShop.experienceSkinIndex != null){
                        this.spineComponent.setSkin("blue" + SkinShop.experienceSkinIndex);
                    }else{
                        this.spineComponent.setSkin("blue" + GameData_red_blue_man.usingSkinIndex);
                    }
                }
            }
            this.playAnim({animName:animName.idle, loop: true, state: animName.idle});
        });

        this.spineNode.scale = 0.7;

        if(!this.custom){
            this.speed = 240;
            this.jumpNum = 740
        }
        let multiplying = ((100 + 5*GameData_red_blue_man.gotSkinCount)/100);

        if(multiplying >= 2 ){
            multiplying = 2;
        }
        if(!GameData_red_blue_man.isGuiding){
            this.speed *= multiplying;
        }
        console.log(this.speed);
        GameControl_red_blue_man.heroState[this.manType] = false;
        this.addHead();
        let boxList = this.node.getComponents(cc.PhysicsBoxCollider);
        for(let i of boxList){
            if(i.tag == 1){
                boxList[1].offset.y = -57;
                boxList[1].size.width = 38;
                boxList[1].size.height = 10;
                boxList[1].apply();
            }
        }
    }

    gameOver(){
        this.heroRigidBody.linearVelocity = cc.v2(0, 0);
        cc.game.emit(emitType.overAnim);
    }

    isShowOver = false;
    overAnim(){
        if(this.isShowOver){
            return;
        }
        if(GameControl_red_blue_man.heroState[colorType.blue] == true &&  GameControl_red_blue_man.heroState[colorType.red] == true){
            this.isShowOver = true;
            //移动到门的中间位置
            this.playAnim({animName:animName.run, loop: true, state:animName.run});
            this.stopRunEffectAnim();
            let posY = this.node.y;
            this.heroRigidBody.gravityScale = 0;
            //判断面部朝向
            this.spineNode.scaleX = this.node.x > this.doorPos ? -0.7 : 0.7;
            //计算现在与门之间的间距
            let distances = Math.abs(this.node.x - this.doorPos);
            let time = distances/200;
            this.node.runAction(
                cc.sequence(
                    cc.moveTo(time, cc.v2(this.doorPos, posY)),
                    cc.callFunc(()=>{
                        this.playAnim({animName:animName.idle, loop: true, state:animName.idle});
                        cc.game.emit(emitType.overAnimFollowUp);
                    }),
                ),
            )
        }
    }

    overCount = 0;
    overGameFollowUp(){
        this.overCount ++;
        if(this.overCount >= 2){
            this.manType == colorType.red ? Music.GamePlayEffect(musicName.Yeah_fire) : Music.GamePlayEffect(musicName.Yeah_ice);
            this.playAnim({animName:animName.celebrate2, loop: false, callback:()=>{
                    this.playAnim({animName:animName.run, loop: true});
                    this.node.runAction(
                        cc.sequence(
                            cc.spawn(
                                cc.moveBy(0.7, cc.v2(0, 20)),
                                cc.scaleTo(0.7, 0.4,0.4)
                            ),
                            cc.callFunc(()=>{
                                this.node.active = false;
                                cc.game.emit(emitType.createOverPage);
                            })
                        )
                    )
                }}
            );
        }
    }

    addHead(){
        let node = new cc.Node();
        node.y = 105;
        node.parent = this.node;
        node.name = "headTip";
        let spr = node.addComponent(cc.Sprite);
        let num = this.manType == colorType.red ? 4 : 3;
        cc.loader.loadRes("Sprite/tb01" + num, cc.SpriteFrame, (err,res)=>{
            spr.spriteFrame = res;
        });
        node.active = this.manType == colorType.red ;
    }

    pushLock = false;
    move(dir){
        if(GameControl_red_blue_man.gameState){
            return;
        }
        if(this.onMoveSide){
            this.node_phy_box.friction = 0;
            this.node_phy_box.apply();
        }

        this.lastAnimState = animName.run;
        this.move_lock = true;
        this.spineNode.scaleX = dir == -1 ? -0.7 : 0.7;
        if(this.isJump){
            this.heroRigidBody.linearVelocity = cc.v2(this.speed * dir * 1.5, this.heroRigidBody.linearVelocity.y);
        }else{
            this.heroRigidBody.linearVelocity = cc.v2(this.speed * dir, this.heroRigidBody.linearVelocity.y);
        }

        if(this.pushStoneAnim){
            Music.specialMusic({name: musicName.stone_Sound, loop: true});
            if(this.pushLock){
                return;
            }
            this.pushLock = true;
            this.playAnim({animName:animName.push, loop: true, state:animName.idle});
        }else{
            if(this.animState == animName.idle){
                this.playAnim({animName:animName.run, loop: true, state:animName.run});
                this.effect_anim({animName: effectAnimName.animation, loop: true});
                return;
            }
        }
    }

    stopMove(cut?){
        if(GameControl_red_blue_man.gameState){
            return;
        }
        this.lastAnimState = animName.idle;
        Music.stopSpecialMusic({name: musicName.stone_Sound});
        if(this.onMoveSide && !cut){
            this.setOnMoveSide(false);
            cc.game.emit(emitType.changeMoveSide, this.manType);
            this.node_phy_box.friction = 0;
            this.node_phy_box.apply();
        }
        this.move_lock = false;
        this.pushLock = false;
        this.heroRigidBody.linearVelocity = cc.v2(0, this.heroRigidBody.linearVelocity.y);
        if(/*this.animState != animName.jump1*/!this.jumpLock){
            this.playAnim({animName:animName.idle, loop: true, state:animName.idle});
            this.playWaveAnim();
        }
        this.stopRunEffectAnim();
    }

    isJump = false;
    jump(){
        if (this.jumpLock || GameControl_red_blue_man.gameState) {
            return;
        }
        if(this.manType == colorType.red){
            Music.GamePlayEffect(musicName.FireJump)
        }else{
            Music.GamePlayEffect(musicName.IceJump)
        }
        this.isJump = true;
        this.jumpLock = true;
        GameControl_red_blue_man.heroState[this.manType] = false;
        this.heroRigidBody.linearVelocity = cc.v2(this.heroRigidBody.linearVelocity.x , this.jumpNum);
        this.playAnim({animName:animName.jump1, loop: false, state:animName.jump1});
        this.stopRunEffectAnim();
        this.impulse();
    }

    judgeJump(){
        GameControl_red_blue_man.heroState[this.manType] = true;
        if(this.isShowOver){
            return;
        }
        this.isJump = false;
        this.jumpLock = false;

        if(GameControl_red_blue_man.gameState){
            this.playAnim({animName:animName.celebrate1, loop: true, state:animName.idle});
            cc.game.emit(emitType.overAnim);
            return;
        }
        /*console.log(this.lastAnimState == animName.idle);
        if(this.lastAnimState == animName.run){
            console.log("进入第一层判断！！！");
            this.playAnim({animName:animName.run, loop: true, state:animName.run});
            this.effect_anim({animName: effectAnimName.animation, loop: true});
            this.heroRigidBody.linearVelocity = cc.v2(this.speed * this.spineNode.scaleX, this.heroRigidBody.linearVelocity.y);
            return;
        }*/
        this.playAnim({animName:animName.idle, loop: true, state:animName.idle});
        this.playWaveAnim();
    }

    //招手动画
    waveAnim(){
        this.playAnim({animName:animName.celebrate1, loop: true});
    }

    //跳跃动画
    jumpAnim(){
        if(/*this.animState == animName.jump1*/this.jumpLock){
            return;
        }
        this.isJump = true;
        this.jumpLock = true;
        this.playAnim({animName:animName.jump1, loop: false, state: animName.jump1});
    }

    //是否开启复活
    isResurgence = false;
    //无敌复活状态
    angerResurgence = false;
    //复活
    resurgence(){
        if(!this.isResurgence){
            return;
        }
        this.heroRigidBody.linearVelocity = cc.v2(0, 0);
        this.playAnim({animName:animName.idle, loop: true, state:animName.idle});
        this.isResurgence = false;
        GameControl_red_blue_man.gameState = false;
        this.isShowOver = false;
        this.spineNode.active = true;
        this.effectSpineComponent.setAnimation(1, effectAnimName.animation2, false);
        cc.director.getPhysicsManager().enabled = true;
        this.node.setPosition(this.initPos);
        let animNode = new cc.Node();

        if(this.angerResurgence){
            return;
        }
        this.angerResurgence = true;
        animNode.parent = this.node;
        animNode.zIndex = 1;
        animNode.y = -58;
        animNode.x = 7;
        this.spineNode.zIndex = 100;
        this.effectSpineNode.zIndex = 200;
        let animComponent = animNode.addComponent(sp.Skeleton);
        animComponent.skeletonData = Welcome.invincibleEffect;
        animComponent.setAnimation(1, "anger", true);
    }

    manDie = false;
    //死亡
    die(){
        if(GameControl_red_blue_man.gameState || this.angerResurgence || GameData_red_blue_man.isGuiding){
            return;
        }
        Music.GamePlayEffect(musicName.Die);
        Setting.shake(1);
        this.isShowOver = true;
        cc.director.getPhysicsManager().enabled = false;
        this.spineNode.active = false;
        GameControl_red_blue_man.gameState = true;
        this.isResurgence = true;
        this.effect_anim({animName: effectAnimName.die, loop: false, callback:()=>{
            ControlScript.instantiate("resurgence")
        }});
    }

    //复活
    resurgenceOver(){
        ControlScript.instantiate("loadShow", (view)=>{
            view.getComponent(LoadShow).show("gameOver", true, false);
        })
    }

    //冲量
    impulse(){
        this.heroRigidBody.applyLinearImpulse(cc.v2(this.heroRigidBody.linearVelocity.x * 2, 0), this.heroRigidBody.getWorldCenter(), true);
    }

    //特效动画
    effect_anim(data){
        if(data.animName == effectAnimName.animation){
            this.effectSpineNode.scaleX = this.spineNode.scaleX < 0 ? -1 : 1;
            this.effectSpineNode.setPosition(cc.v2(-(this.spineNode.scaleX < 0 ? -1 : 1) * ((this.node.width + this.effectSpineNode.width)/2 + 50), -60));
            this.playRunEffect = true;
        }else{
            this.effectSpineNode.setPosition(cc.v2(0,0));
            this.playRunEffect = false;
        }
        this.animation(data, this.effectSpineComponent);
    }

    //播放动画
    playAnim(data){
        if(data.state){
            this.animState = data.state;
        }
        this.animation(data, this.spineComponent);
    }

    animation(data, animComponent){
        let anim =animComponent.setAnimation(1,data.animName, data.loop);
        animComponent.timeScale = 1.3;
        //是否需要动画回调
        if(data.callback){
            animComponent.setTrackCompleteListener(anim, ()=>{
                data.callback();
            });
        }
    }

    //停止行走 特效动画
    stopRunEffectAnim(){
        if(this.playRunEffect){
            this.effectSpineComponent.setAnimation(1, effectAnimName.animation2, false);
        }
    }

    //改变 是否碰撞到门
    changeContactDoor(state, posX?){
        this.contactDoor = state;
        if(posX){
            this.doorPos = posX;
        }
    }

    //播放招手动画
    playWaveAnim(){
        this.scheduleOnce(()=>{
            if(this.contactDoor && this.animState == animName.idle){
                this.playAnim({animName:animName.celebrate1, loop: true, state:animName.idle});
            }
        },0.1);
    }

    //改变状态
    setOnMoveSide(state){
        this.onMoveSide = state;
    }
    //获得状态
    getOnMoveSide(){
        return this.onMoveSide;
    }

    //无视所有跳跃条件
    isBridge = false;

    update (dt) {
        if((!this.move_lock || GameControl_red_blue_man.gameState) && !this.onMoveSide){
            let speed = this.heroRigidBody.linearVelocity;
            speed.x = 0;
            this.heroRigidBody.linearVelocity = speed;
        }
    }
}
